﻿using Microsoft.EntityFrameworkCore;
using SJ.Platform.Common;
using SJ.Platform.EFCore.Model;
using SJ.Platform.EFCore.Model.AuthorityManager;
using SJ.Platform.Extend.ModelExtend;
using SJ.Platform.Extend.ModelExtend.SysAuthorityExt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SJ.Platform.EFCore.DBOperation.DBOperation.MySQL.Sys
{
    /// <summary>
    /// 权限操作类
    /// </summary>
    public class Sys_AuthorityHandle
    {
        private readonly SJDBContext _context;

        public Sys_AuthorityHandle(SJDBContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(SysAuthority entity)
        {
            try
            {
                _context.SysAuthorities.Add(entity);
                return await _context.SaveChangesAsync() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>Create", ex);
                return false;
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(SysAuthority entity)
        {
            try
            {
                _context.Entry(entity).State = EntityState.Modified;
                return await _context.SaveChangesAsync() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>Update", ex);
                return false;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> Delete(SysAuthority entity)
        {
            try
            {
                _context.SysAuthorities.Remove(entity);
                return await _context.SaveChangesAsync() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>Delete", ex);
                return false;
            }
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByIdAsync(string id)
        {
            try
            {
                var entity = _context.SysAuthorities.Find(id);
                if (entity != null)
                {
                    _context.SysAuthorities.Remove(entity);
                    return await _context.SaveChangesAsync() > 0;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>DeleteById", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<SysAuthority> GetEntityByIdAsync(string id)
        {
            try
            {
                return await _context.SysAuthorities.FindAsync(id);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>GetEntityById", ex);
            }
            return null;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public List<SysAuthority> GetAll(int pageNumber, int pageSize, ref int count, Expression<Func<SysAuthority, bool>> condition = null)
        {
            try
            {
                var query = _context.SysAuthorities.AsQueryable();

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }
                count = query.Count();
                // 应用分页
                var skip = (pageNumber - 1) * pageSize;
                query = query.Skip(skip).Take(pageSize);

                // 执行查询并返回结果
                return query.ToList();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>GetAll  page", ex);
            }
            return null;
        }

        /// <summary>
        /// 分页获取所有权限
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<(List<SysAuthorityExtend> authoriesExtList, int count)> GetAllAsync(int pageNumber, int pageSize, Expression<Func<SysAuthority, bool>> condition = null)
        {
            try
            {
                var query = _context.SysAuthorities.AsQueryable();

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }

                //总条数
                int count = await query.CountAsync();

                // 应用分页
                var skip = (pageNumber - 1) * pageSize;
                query = query.Skip(skip).Take(pageSize);

                // 执行查询并返回结果
                var authories = await query.ToListAsync();

                List<SysAuthorityExtend> authoriesExtList = new List<SysAuthorityExtend>();
                if (authories != null && authories.Count > 0)
                {
                    authoriesExtList = authories.Select(authority => new SysAuthorityExtend
                    {
                        Id = authority.Id,
                        AuthorityName = authority.AuthorityName,
                        AuthorityType = authority.AuthorityType,
                        MenuId = authority.MenuId,
                        Pid = authority.Pid,
                        AddTime = authority.AddTime,
                        AddUserId = authority.AddUserId,
                        EditTime = authority.EditTime,
                        EditUserId = authority.EditUserId
                    }).ToList();

                    //父级权限
                    List<string> aPId = new List<string>();
                    foreach (var a in authories)
                    {
                        if (!string.IsNullOrEmpty(a.Pid) && !aPId.Contains(a.Pid))
                        {
                            aPId.Add(a.Pid);
                        }
                    }
                    List<SysAuthority> aList = _context.SysAuthorities.FromSqlRaw("select * FROM sys_authority where Id in ('" + string.Join("','", aPId.ToArray()) + "')").ToList();

                    foreach (SysAuthorityExtend authority in authoriesExtList)
                    {
                        authority.PName = aList.Find(a => a.Id == authority.Pid) != null ? aList.Find(a => a.Id == authority.Pid).AuthorityName : "";
                    }

                    //菜单名称
                    List<string> mPId = new List<string>();
                    foreach (var a in authories)
                    {
                        if (!string.IsNullOrEmpty(a.MenuId) && !mPId.Contains(a.MenuId))
                        {
                            mPId.Add(a.MenuId);
                        }
                    }

                    List<Model.MenuManager.SysMenu> mList = _context.SysMenus.FromSqlRaw("select * FROM sys_menu where Id in ('" + string.Join("','", mPId.ToArray()) + "')").ToList();

                    foreach (SysAuthorityExtend authority in authoriesExtList)
                    {
                        authority.MenuName = mList.Find(m => m.Id == authority.MenuId) != null ? mList.Find(m => m.Id == authority.MenuId).MenuName : "";
                    }
                }

                return (authoriesExtList, count);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>GetAllAsync  page", ex);
            }
            return (null, 0);
        }

        /// <summary>
        /// 获取所有权限
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<List<SysAuthority>> GetAllAsync(Expression<Func<SysAuthority, bool>> condition = null)
        {
            try
            {
                IQueryable<SysAuthority> query = _context.SysAuthorities;

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }

                // 执行查询并返回结果
                return await query.ToListAsync();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>GetAll", ex);
            }
            return null;
        }

        ///// <summary>
        ///// 根据角色ID获取所有权限
        ///// </summary>
        ///// <param name="roleId"></param>
        ///// <returns></returns>
        //public async Task<List<SysAuthorityExtend>> GetAllByRoleId(string roleId)
        //{
        //    try
        //    {
        //        var query = from authority in _context.SysAuthorities
        //                    join r in _context.SysRAuthoritytoroles on authority.Id equals r.AuthorityId
        //                    where r.RoleId == roleId
        //                    select authority;

        //        var authorityList = await query.ToListAsync();

        //        List<SysAuthorityExtend> sysAuthorityExtendList = new List<SysAuthorityExtend>();

        //        BuildChild(sysAuthorityExtendList, authorityList, authorityList, 1, null);

        //        return sysAuthorityExtendList;
        //    }
        //    catch (Exception ex)
        //    {
        //        LogManager.WriteError("Sys_AuthorityHandle=>GetAllByRoleId", ex);
        //    }
        //    return null;
        //}
        /// <summary>
        /// 获取所有层级的权限
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysAuthorityExtend>> GetAllAuthoritiesToLevelAsync(string roleId)
        {
            try
            {
                //角色与权限关系
                IQueryable<SysRAuthoritytorole> queryToRole = _context.SysRAuthoritytoroles;
                var relationList = await queryToRole.Where(r => r.RoleId == roleId).ToListAsync();

                //获取所有权限
                IQueryable<SysAuthority> query = _context.SysAuthorities;
                var authorityList = await query.ToListAsync();

                //生成扩展的权限列表
                List<SysAuthorityExtend> sysAuthorityExtendList = new List<SysAuthorityExtend>();
                BuildChild(sysAuthorityExtendList, authorityList, authorityList, 1, relationList);

                return sysAuthorityExtendList;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>GetAllByRoleId", ex);
            }
            return null;
        }

        /// <summary>
        /// 递归生成子级
        /// </summary>
        /// <param name="sysAuthorityExtendList"></param>
        /// <param name="authorityList"></param>
        /// <param name="sourceList"></param>
        /// <param name="level"></param>
        private void BuildChild(List<SysAuthorityExtend> sysAuthorityExtendList, List<SysAuthority> authorityList, List<SysAuthority> sourceList, int level, List<SysRAuthoritytorole> relationList)
        {
            try
            {
                if (authorityList != null && authorityList.Count > 0)
                {
                    var pList = level == 1 ? authorityList.Where(a => string.IsNullOrEmpty(a.Pid) || a.Pid == null).ToList() : authorityList;
                    foreach (var authority in pList)
                    {
                        SysAuthorityExtend sysAuthorityExtend = new SysAuthorityExtend();
                        sysAuthorityExtend.Id = authority.Id;
                        sysAuthorityExtend.AuthorityName = authority.AuthorityName;
                        sysAuthorityExtend.Pid = authority.Pid;
                        sysAuthorityExtend.AuthorityType = authority.AuthorityType;
                        sysAuthorityExtend.MenuId = authority.MenuId;
                        sysAuthorityExtend.AddUserId = authority.AddUserId;
                        sysAuthorityExtend.AddTime = authority.AddTime;
                        sysAuthorityExtend.EditTime = authority.EditTime;
                        sysAuthorityExtend.EditUserId = authority.EditUserId;

                        if (relationList != null && relationList.Count > 0)
                        {
                            var rList = relationList.Where(r => r.AuthorityId == authority.Id);
                            if (rList != null && rList.Count() > 0)
                            {
                                sysAuthorityExtend.Checked = true;
                            }
                        }

                        var childAuthorityList = sourceList.Where(c => c.Pid == authority.Id).ToList();
                        if (childAuthorityList != null && childAuthorityList.Count > 0)
                        {
                            if (sysAuthorityExtend.childAuthorityList == null)
                            {
                                sysAuthorityExtend.childAuthorityList = new List<SysAuthorityExtend>();
                            }
                            BuildChild(sysAuthorityExtend.childAuthorityList, childAuthorityList, sourceList, 2, relationList);
                        }

                        sysAuthorityExtendList.Add(sysAuthorityExtend);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>BuildChild", ex);
            }
        }

        /// <summary>
        /// 设置权限
        /// </summary>
        /// <param name="authorities"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<bool> SetAuthorityToRoleAsync(SysAuthorityConfigExtend authorities, string userId)
        {
            try
            {
                //先删除角色对应的所有权限
                int count = _context.Database.ExecuteSqlRaw($"delete from sys_r_authoritytorole where RoleId='{authorities.RoleId}';");

                //再创建新的关系
                List<SysRAuthoritytorole> sysRAuthoritytoroleList = new List<SysRAuthoritytorole>();
                BuildAuthorityToRoleModel(authorities.RoleId, authorities.childAuthorityList, sysRAuthoritytoroleList, userId);
                if (sysRAuthoritytoroleList.Count > 0)
                {
                    return await _context.SaveChangesAsync() > 0;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_AuthorityHandle=>DeleteById", ex);
            }
            return false;
        }
        /// <summary>
        /// 创建权限与角色实体对象
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="authorityExtends"></param>
        /// <param name="sysRAuthoritytoroleList"></param>
        /// <param name="userId"></param>
        private void BuildAuthorityToRoleModel(string roleId, List<SysAuthorityExtend> authorityExtends, List<SysRAuthoritytorole> sysRAuthoritytoroleList, string userId)
        {
            if (authorityExtends != null && authorityExtends.Count > 0)
            {
                foreach (SysAuthorityExtend authorityExtend in authorityExtends)
                {
                    if ((bool)authorityExtend.Checked)
                    {
                        SysRAuthoritytorole sysRAuthorityToRole = new SysRAuthoritytorole()
                        {
                            Id = Guid.NewGuid().ToString(),
                            RoleId = roleId,
                            AuthorityId = authorityExtend.Id,
                            AddTime = DateTime.Now,
                            AddUserId = userId
                        };
                        _context.SysRAuthoritytoroles.Add(sysRAuthorityToRole);
                        sysRAuthoritytoroleList.Add(sysRAuthorityToRole);
                    }

                    if (authorityExtend.childAuthorityList != null && authorityExtend.childAuthorityList.Count > 0)
                    {
                        BuildAuthorityToRoleModel(roleId, authorityExtend.childAuthorityList, sysRAuthoritytoroleList, userId);
                    }
                }

            }
        }
    }
}